package com.acme.bankapp.service.bank;

import com.acme.bankapp.domain.account.*;
import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.client.*;
import com.acme.bankapp.exceptions.*;
import com.acme.bankapp.service.bank.BankService;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class BankDataLoaderService {

    public static void load(final Bank bank, final String path)
            throws FileNotFoundException {

        FileReader in = new FileReader(path);
        BufferedReader bufIn = new BufferedReader(in);

        try {
            String line = bufIn.readLine();
            while (line != null) {
                addClientFromString(bank, line);
                line = bufIn.readLine();
            }

        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            try {
                bufIn.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static boolean addClientFromString(final Bank bank, final String line) {
        String[] clientLine = line.split(";");

        Map<String, String> paramValueMap = new HashMap<String, String>();
        for (String aClientLine : clientLine) {
            String[] paramValue = aClientLine.split("=");
            paramValueMap.put(paramValue[0], paramValue[1]);
        }

        try {
            createBankEntities(paramValueMap, bank);

        } catch (BankException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    private static void createBankEntities(final Map<String, String> paramValueMap, final Bank bank)
            throws BankException {

        String accountType =    paramValueMap.get("accounttype");
        String balance =        paramValueMap.get("balance");
        String overdraft =      paramValueMap.get("overdraft");
        String name =           paramValueMap.get("name");
        String gender =         paramValueMap.get("gender");

        Gender genderType = null;
        if ("m".equals(gender)) {
            genderType = Gender.MALE;

        } else if ("f".equals(gender)) {
            genderType = Gender.FEMALE;

        } else {
            throw new BankException("Invalid gender");
        }

        Client client = null;
        try {
            client = BankService.addClient(bank, name, genderType);

        } catch (ClientExistsException e) {
            System.out.println("Warn: client exists");
            client = e.getClient();
        }

        addAccount(accountType, balance, overdraft, client);
    }

    private static void addAccount(final String accountType, final String balance, final String overdraft, final Client client)
            throws BankException {

        double balanceAsDouble = 0;
        try {
            balanceAsDouble = Double.parseDouble(balance);

        } catch (NumberFormatException e) {
            throw new BankException("Unable to parse balance");
        }

        double overdraftAsDouble = 0;
        try {
            overdraftAsDouble = Double.parseDouble(overdraft);

        } catch (NumberFormatException e) {
            overdraftAsDouble = 0;
        }

        Account account = null;
        if ("c".equals(accountType)) {
            account = new CheckingAccount(balanceAsDouble, overdraftAsDouble);

        } else if ("s".equals(accountType)) {
            account = new SavingAccount(balanceAsDouble);

        } else {
            throw new BankException("Invalid account type");
        }

        client.addAccount(account);
    }
}
